//
//  ServerHelper.m
//  BSValue2
//
//  Created by Rainbow on 12/21/10.
//  Copyright 2010 iTotemStudio. All rights reserved.


#import "ServiceHelper.h"
#import "Reachability.h"
#import "CJSONDeserializer.h"
#import "CacheData.h"
#import "PersistenceData.h"
#import "Letter.h"
#import "Word.h"
#import "Meaning.h"
#import "Advertising.h"
#import "UtilHelper.h"
#import "CacheData.h"
#import "UserManager.h"

@implementation ServiceHelper

static ServiceHelper *_sharedInst = nil;
static NSString *ServerBaseUrl = HOTWORD_BASE_URL;

+ (id) sharedService
{
	@synchronized(self){
		if(_sharedInst == nil)
		{
			_sharedInst = [[self alloc] init];
		}
	}
	return _sharedInst;
}

-(id) init
{
	if ((self = [super init])) {
		CallBacks = [[NSMutableDictionary alloc] init];
		[self restore];
	}
	return self;
}

- (void)addLetterInSubThread:(NSDictionary *)letterAndCategory
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [[PersistenceData sharedData] addLetter:[letterAndCategory objectForKey:@"letter"] category:[letterAndCategory objectForKey:@"category"]];
    [pool release];
}

-(void)requestDone:(ASIFormDataRequest *)request
{
	// NSLog(@"feed back for action : %@, is : %@",request.requestFlagMark,[request responseString]);
	NSString *response = [request responseString];
    response = [response stringByReplacingOccurrencesOfString:@"\t" withString:@""];
    response = [response stringByReplacingOccurrencesOfString:@"\n" withString:@""];
	NSData *jsonData;
    if (response!= nil && ![@"" isEqualToString:response] && [[response substringWithRange:NSMakeRange(0,1)] isEqualToString: @"["] ) {
		jsonData = [[[@"{\"data\":" stringByAppendingString:response ] stringByAppendingString:@"}"] dataUsingEncoding:NSUTF8StringEncoding];
	}else {
		jsonData = [response  dataUsingEncoding:NSUTF8StringEncoding];
	}
    
	NSDictionary *result = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:nil];    
//	NSLog(@"result = %@", result);
	NSDictionary *targetCallBack = [CallBacks objectForKey:request.requestFlagMark];
	
	BOOL shouldTriggerErrorHandler = NO;
	if ([[result objectForKey:@"error_code"] intValue] == 100) {
		shouldTriggerErrorHandler = YES;
	}
    
	switch (request.RequestType) { 
        case HotWordRequestTypeGetWords:
        {
            NSDictionary *resultDic = (NSDictionary *)result;
            NSArray *words = [resultDic objectForKey:@"words"];
            NSString *letterName = [resultDic objectForKey:@"letter"];
            NSString *category = [resultDic objectForKey:@"category"];
            if ([words isKindOfClass:[NSArray class]]) {
                Letter *letter = [[[Letter alloc] init] autorelease];
                letter.learnIndex = [NSNumber numberWithInt:0];
                letter.practiceIndex = [NSNumber numberWithInt:0];
                letter.letter = letterName;
                letter.updateTimestamp = [NSNumber numberWithLongLong:0];
                for (NSDictionary *wordDic in words) {
                    Word *word = [[[Word alloc] init] autorelease];
                    word.wordId = [UtilHelper getStringValue:[wordDic objectForKey:@"wordId"]];
                    word.content = [UtilHelper getStringValue:[wordDic objectForKey:@"content"]];
                    word.slug = [UtilHelper getStringValue:[wordDic objectForKey:@"slug"]];
                    word.timestamp = [UtilHelper getStringValue:[wordDic objectForKey:@"createTime"]];
                    if ([word.timestamp longLongValue] > [letter.updateTimestamp longLongValue]) {
                        letter.updateTimestamp = [NSNumber numberWithLongLong:[word.timestamp longLongValue]];
                    }
                    if ([[wordDic objectForKey:@"meanings"] isKindOfClass:[NSArray class]]) {
                        for (NSDictionary *meaningDic in [wordDic objectForKey:@"meanings"]) {
                            Meaning *meaning = [[[Meaning alloc] init] autorelease];
                            meaning.chineseTranslate = [UtilHelper getStringValue:[meaningDic objectForKey:@"cnTranslate"]];
                            meaning.englishTranslate = [UtilHelper getStringValue:[meaningDic objectForKey:@"engTranslate"]];
                            
                            if ([[meaningDic objectForKey:@"synonyms"] isKindOfClass:[NSArray class]]) {
                                for (NSDictionary *synonymsDic in [meaningDic objectForKey:@"synonyms"]) {
                                    NSString *synonym = [UtilHelper getStringValue:[synonymsDic objectForKey:@"content"]];
                                    if (synonym) {
                                        [meaning.synonyms addObject:synonym];
                                    }
                                }
                            }
                            
                            if ([[meaningDic objectForKey:@"antonyms"] isKindOfClass:[NSArray class]]) {
                                for (NSDictionary *antonymDic in [meaningDic objectForKey:@"antonyms"]) {
                                    NSString *antonym = [UtilHelper getStringValue:[antonymDic objectForKey:@"content"]];
                                    if (antonym) {
                                        [meaning.antonyms addObject:antonym];
                                    }
                                }
                            }
                            
                            if ([[meaningDic objectForKey:@"sentences"] isKindOfClass:[NSArray class]]) {
                                for (NSDictionary *sentenceDic in [meaningDic objectForKey:@"sentences"]) {
                                    NSString *sentence = [UtilHelper getStringValue:[sentenceDic objectForKey:@"content"]];
                                    if (sentence) {
                                        [meaning.sentences addObject:sentence];
                                    }
                                }
                            }
                            
                            [word.meanings addObject:meaning];
                        }
                        
                    }
                    [letter.words addObject:word];
                }
                if (letter.letter != nil && [letter.words count] > 0) {
                    NSString *categoryName = nil;
                    if ([@"0" isEqualToString:category]) {
                        categoryName = SAT_WORDS;
                    }
                    else if ([@"1" isEqualToString:category]) {
                        categoryName = GRE_WORDS;
                    }                    
                    else if ([@"2" isEqualToString:category]) {
                        categoryName = IBT_WORDS;
                    }
                    if ([categoryName isEqualToString:[CacheData sharedData].currentCategory]) {
                        NSDictionary *addingLetterAndCategory = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:letter, categoryName, nil] forKeys:[NSArray arrayWithObjects:@"letter",@"category", nil]];
                        [self performSelectorInBackground:@selector(addLetterInSubThread:) withObject:addingLetterAndCategory];
                    }else{
                        return;
                    }
                }
            }
        }
            break;
            
        case HotWordRequestTypeCheckLetterUpdate:
        {
            [[CacheData sharedData].needUpdateLetters removeAllObjects];
            NSDictionary *resultDic = (NSDictionary *)result;
            NSDictionary *updateStatus = [resultDic objectForKey:@"letters"];
            for (NSString *letterName in [[CacheData sharedData].savedLetters allKeys]) {
                if ([updateStatus objectForKey:letterName]) {
                    Letter *letter = [[CacheData sharedData].savedLetters objectForKey:letterName];
                    if ([letter.updateTimestamp longLongValue] < [[updateStatus objectForKey:letterName] longLongValue]) {
                        [[CacheData sharedData].needUpdateLetters addObject:letterName];
                    }
                }
            }
        }
            break;
            
        case HotWordRequestTypeGetAdvertising:
        {
            NSMutableArray *advertisings = [NSMutableArray array];
            NSDictionary *resultDic = (NSDictionary *)result;
            NSArray *advertisingDics = [resultDic objectForKey:@"advertisings"];
            for (NSDictionary *advertisingDic in advertisingDics) {
                Advertising *advertising = [[[Advertising alloc] init] autorelease];
                advertising.adId = [UtilHelper getStringValue:[advertisingDic objectForKey:@"adId"]];
                advertising.title = [UtilHelper getStringValue:[advertisingDic objectForKey:@"title"]];
                advertising.summary = [UtilHelper getStringValue:[advertisingDic objectForKey:@"summary"]];
                advertising.details = [UtilHelper getStringValue:[advertisingDic objectForKey:@"details"]];
                advertising.createTime = [UtilHelper getStringValue:[advertisingDic objectForKey:@"createTime"]];
                advertising.category = [UtilHelper getStringValue:[advertisingDic objectForKey:@"category"]];
                advertising.adUrl = [UtilHelper getStringValue:[advertisingDic objectForKey:@"adUrl"]];
                [advertisings addObject:advertising];
            }
            [[PersistenceData sharedData] setAdvertisings:advertisings];
            
            NSString *adUpdateCount = [UtilHelper getStringValue:[resultDic objectForKey:@"count"]];
            
            [[PersistenceData sharedData] setAdUpdateCount:[adUpdateCount intValue]];
            
        }
            break;
        default:
            break;
    }
	
	if(shouldTriggerErrorHandler){
		[[targetCallBack objectForKey:@"delegate"] performSelector:NSSelectorFromString([targetCallBack objectForKey:@"onfailed"]) withObject:@"auth error"];
	}else {
		[[targetCallBack objectForKey:@"delegate"] performSelector:NSSelectorFromString([targetCallBack objectForKey:@"onsuccess"]) withObject:result];
	}
	
	[CallBacks removeObjectForKey:request.requestFlagMark];
}

-(void)requestWentWrong:(ASIFormDataRequest *)request
{
	NSDictionary *targetCallBack = [CallBacks objectForKey:request.requestFlagMark];
    switch (request.RequestType) {
        case HotWordRequestTypeSendMsg:
        {
            [CacheData sharedData].tempMessage.isSentFailed = [NSNumber numberWithBool:YES];
        }
            break;
        default:
            break;
    }
	// NSLog(@"request %@ went wrong with status code %d, and feedback body %@",request.requestFlagMark, [request responseStatusCode], [request responseString]);
	[[targetCallBack objectForKey:@"delegate"] performSelector:NSSelectorFromString([targetCallBack objectForKey:@"onfailed"]) withObject:@"connection error"];
	[CallBacks removeObjectForKey:request.requestFlagMark];
}

-(ASIFormDataRequest *)requestServerForMethod:(HotWordRequestType)methodType 
							   WithParameters:(NSDictionary *)parameters 
							AndCallBackScope:(id)callBackDelegate 
								AndSuccessSel:(NSString *)successSelector 
								 AndFailedSel:(NSString *)failedSelector
{
	NSDictionary *tempDic = [NSDictionary dictionaryWithObjectsAndKeys:callBackDelegate, @"delegate", successSelector, @"onsuccess", failedSelector, @"onfailed", nil];
	[tempDic retain];
	
    BOOL isPost = NO;
    NSString *requestUrl = @"";
    switch (methodType) {
        case HotWordRequestTypeGetWords:
            requestUrl = [NSString stringWithFormat:@"%@%@",ServerBaseUrl,@"getwords.php?"];
            break;
        case HotWordRequestTypeGetAdvertising:
            requestUrl = [NSString stringWithFormat:@"%@%@",ServerBaseUrl,@"getadvertisings.php?"];
            break;
        case HotWordRequestTypeCheckLetterUpdate:
            requestUrl = [NSString stringWithFormat:@"%@%@",ServerBaseUrl,@"checkWordUpdateStatus.php?"];
            break;
        case HotWordRequestTypeRegister:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"register.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeLogin:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"login.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeUpdateInfo:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"updateInfo.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeUpdateGeo:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"updateGeo.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeUploadPic:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"uploadPic.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeListUser:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"listUser.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeSendMsg:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"sendMsg.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeReceiveMsg:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"receiveMsg.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeGetUserInfo:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"userInfo.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeUploadToken:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"updateToken.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeCheckUpdate:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"checkUpdate.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeListSchool:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"listSchool.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeListUserBySchool:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"listUserBySchool.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeResetNews:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/wordhot/controllers/",@"resetMessageCount.php?"];
            isPost = YES;
        case HotWordRequestTypeGetSATAdvertising:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"getadvertising.php"];
            break;
        case HotWordRequestTypeUpdateFilter:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"updateFilter.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeListUserByDreamSchool:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"listUserByDreamSchool.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeListUserByTeacher:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"listUserByTeacher.php"];
            isPost = YES;
            break;
        case HotWordRequestTypeListUserByExam:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"listUserByExam.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeListUserByStudyHall:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"listUserByStudyHall.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeListUserByGreMajor:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"listUserByGreMajor.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeGetQuestionTags:
            requestUrl = [NSString stringWithFormat:@"%@%@",ServerBaseUrl,@"gettags.php"];
            break;
        case HotWordRequestTypeGetQuestion:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"getQuestions.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeAddQuestion:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"addQuestion.php?"];
            isPost = YES;
            break;
        case HotWordRequestTypeGetUserQuestion:
            requestUrl = [NSString stringWithFormat:@"%@%@",@"http://www.wordhot.net/json/",@"getUserQuestions.php?"];
            isPost = YES;
            break;

        default:
            break;
    }
    
    if (!isPost) {
        NSArray *paraKeys = [parameters allKeys];
        if([paraKeys count] > 0)
        {
            for(NSInteger i = 0; i < [paraKeys count] ; i++)
            {
                
                if (i == [paraKeys count] - 1) {
                    requestUrl = [requestUrl stringByAppendingFormat:@"%@=%@",[paraKeys objectAtIndex:i],[parameters objectForKey:[paraKeys objectAtIndex:i]]];
                }
                else
                {
                    requestUrl = [requestUrl stringByAppendingFormat:@"%@=%@&",[paraKeys objectAtIndex:i],[parameters objectForKey:[paraKeys objectAtIndex:i]]];
                }
            }
        }
    }
    
    NSLog(@"requestUrl: %@", requestUrl);
    
	ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:[requestUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
    if (isPost) {
        [request setRequestMethod:@"POST"];
        ASIPostFormat postFormat = ASIURLEncodedPostFormat;
        NSArray *paraKeys = [parameters allKeys];
        if([paraKeys count] > 0)
        {
            for(NSInteger i = 0; i < [paraKeys count] ; i++)
            {
                NSString *key = [paraKeys objectAtIndex:i];
                if ([[parameters objectForKey:key] isKindOfClass:[UIImage class]]) {
                    UIImage* image = [parameters objectForKey:key];
                    NSData* data = UIImageJPEGRepresentation(image, 0.8);
                    [request addData:data withFileName:[NSString stringWithFormat:@"headimage_%@.jpg", [UserManager sharedManager].currentUser.userId] andContentType:@"image/jpeg" forKey:key];
                }
                else {
                    [request addPostValue:[parameters objectForKey:key] forKey:key];
                    NSLog(@"key: %@   value:%@ \n",key, [parameters objectForKey:key]);
                }
            }
        }
        request.postFormat = postFormat;
    }
    else {
        
        [request setRequestMethod:@"GET"];
    }
    
	request.requestFlagMark = [self getTimeStamp];
	request.RequestType = methodType;
	request.responseEncoding = NSUTF8StringEncoding;
    request.shouldAttemptPersistentConnection = NO;
	[CallBacks setObject:tempDic forKey:request.requestFlagMark];
	
	[tempDic release];
	[request setDelegate:self];
	[request setDidFinishSelector:@selector(requestDone:)];
	[request setDidFailSelector:@selector(requestWentWrong:)];
	[request startAsynchronous];
    [request setTimeOutSeconds:30];
	return request;
}
-(BOOL)checkNetwork:(NSString *)errorMessage
{
	Reachability *reachAblility = [Reachability reachabilityForInternetConnection];
	
	if (![reachAblility isReachable]) {
		if (errorMessage == nil) {
			return NO;
		}
		UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"无网络连接", @"") message:errorMessage delegate:self cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles:nil];
		[alertView show];
		[alertView release];
		return NO;
	}
	return YES;
	
}

-(NSString *)getTimeStamp{
	NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970];
	return [NSString stringWithFormat:@"%f",timestamp];
}

- (NSUInteger)retainCount{
	return NSUIntegerMax;
}

- (oneway void)release{
}

- (id)retain{
	return _sharedInst;
}

- (id)autorelease{
	return _sharedInst;
}

- (void) restore{
	
}

-(void) dealloc
{
	[CallBacks release];
	[super dealloc];
}

@end
